#include "mainclass.h"
#include "ui_mainclass.h"
#include <QtCore/QCoreApplication>
#include "Unit.h"

Unit::Unit(bool flying, bool red, int dmg, int hp, int spd, int rng, int rld, int wid, int ht, int rfrsh, QString atk, QString def, void *eng, Ui::MainClass *u) {

    ui = u;

    engine = eng;

    width = wid;
    height = ht;

    frameDelay = rfrsh;

    isFlying = flying;
    isRed = red;
    hitpoints = hp;
    speed = spd;
    attackRange = rng;
    damage = dmg;

    reloadLimit = rld;
    reloadGague = rld;
    isLoaded = true;
    isAttacking = false;

    walkFrameIndex = 0;
    steadyFrameIndex = 0;
    attackFrameIndex = 0;
    stance = 0;

    walkSprite = new QList <QPixmap*> ();
    steadySprite = new QList <QPixmap*> ();
    attackSprite = new QList <QPixmap*> ();


    frameTimer = new QTimer ();
    moveTimer = new QTimer ();

    displayLabel = new QLabel(ui->battleField);
    displayLabel->setStyleSheet("background-color: rgba(255, 255, 255, 0);");

    attackType = atk;
    defenseType = def;

    if (isFlying) {
        displayLabel->setAlignment(Qt::AlignTop);
        yCoord = 0;
        defenseType = "Air";
    }
    else {
        displayLabel->setAlignment(Qt::AlignBottom);
        yCoord = ui->battleField->geometry().height() - this->height;
    }

    if(isRed)
        xCoord = 0 - this->width;
    else
        xCoord = ui->battleField->geometry().width() + this->width;

    position = (xCoord + width)/2;

    displayLabel->setGeometry(xCoord,yCoord,width,height);



}

void Unit::buildSpriteBase(QList<QPixmap *> *walk, QList<QPixmap *> *attack, QList<QPixmap *> *steady) {
    walkSprite = walk;
    attackSprite = attack;
    steadySprite = steady;
}

void Unit::wakeUnit() {

    displayLabel->show();
    currentSprite = walkSprite->value(0);
    displayLabel->setPixmap(*currentSprite);
    consciousness = new QTimer ();

    connect(frameTimer,SIGNAL(timeout()),this,SLOT(refreshFrame()));
    connect(moveTimer,SIGNAL(timeout()),this,SLOT(move()));
    connect(consciousness,SIGNAL(timeout()),this,SLOT(brain()));

    frameTimer->start(frameDelay);
    moveTimer->start(500/speed);
    consciousness->start(5);
}

void Unit::brain() {
    if(((BattleEngine*)engine)->anyAttackableEnemyUnitsInRange(this)) {
        Unit* target = ((BattleEngine*)engine)->getNearestEnemyUnitFromSet(this,((BattleEngine*)engine)->getAttackableEnemyUnits(this));
        if(moveTimer->isActive())
            moveTimer->stop();

        if(isLoaded) {
            attack(target);
        }
        else {
            if(stance != 2)
                stand(); //set stance to steady
            reloadGague++;
            if (reloadGague >= reloadLimit)
                isLoaded = true;
        }
    }
    else {
        if(!moveTimer->isActive()) {
            stance = 0;
            walkFrameIndex = 0;
            moveTimer->start(500/speed);
        }
    }

}

void Unit::takeDamage(int amount) {
    hitpoints -= amount;
}

void Unit::move() { //Displaces the unit
    stance = 0;
    if(isRed)
        xCoord++;
    else
        xCoord--;
    displayLabel->move(xCoord,yCoord);
    position = (xCoord + width)/2;
}

void Unit::attack(Unit* target) {

    reloadGague = 0;
    isLoaded = false;

    attackFrameIndex = 0;

    crosshair = target;
    stance = 1;
    consciousness->stop();
}

void Unit::stand() {
    steadyFrameIndex = 0;
    stance = 2;
}

void Unit::refreshFrame() { //Sets the sprite appropriate for the current stance
    switch(stance) {
        case 0:
            currentSprite = walkSprite->value(walkFrameIndex);
            walkFrameIndex++;
            walkFrameIndex %= walkSprite->size();
            break;
        case 1:
            currentSprite = attackSprite->value(attackFrameIndex);
            attackFrameIndex++;
            attackFrameIndex %= attackSprite->size();
            if(attackFrameIndex >= attackSprite->size() - 1) {
                crosshair->takeDamage(damage);
                crosshair = NULL;
                consciousness->start(5);
            }
            break;
        case 2:
            currentSprite = steadySprite->value(steadyFrameIndex);
            steadyFrameIndex++;
            steadyFrameIndex %= steadySprite->size();
            break;
        default:
            //do nothing;
            break;
    }
    displayLabel->setPixmap(*currentSprite);
}

void Unit::setFrameRate(int arg) { //Sets the frame rate
    frameDelay = arg;
    frameTimer->setInterval(frameDelay);
}

void Unit::setSpeed(int arg) { //Sets speed in which unit will travel
    speed = arg;
    moveTimer->setInterval(arg);
}

QString Unit::getAttackType() {
    return attackType;
}

QString Unit::getDefenseType() {
    return defenseType;
}

bool Unit::getFaction() {
    return isRed;
}

int Unit::getPosition() {
    return position;
}

int Unit::getAttackRange() {
    return attackRange;
}

int Unit::getHP(){
    return hitpoints;
}

void Unit::freeze() {
    frameTimer->stop();
    moveTimer->stop();
    consciousness->stop();
}

Unit::~Unit()
{
    setParent(NULL);
    delete this;
}

